﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq; 
using System.Text;
using System.Windows.Forms;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using System.Reflection;
using System.IO;
using System.Diagnostics;
using Microsoft.Win32;

namespace CSP.Package.Controls
{
    public partial class ExtendInternetWebApplication : UserControl, IInstallationControl
    {

        private const string _executionPath = @"InternetPortal\ExtendWebApplication.bat";

        public ExtendInternetWebApplication()
        {
            InitializeComponent();
        }

        private string GetWebApplicationUrl()
        {
            string result = chkSSL.Checked ? "https://" : "http://";
            result += txbHostHeader.Text.Length == 0 ? "localhost" : txbHostHeader.Text;
            result += txbPort.Text.Length == 0 ? string.Empty : ":" + txbPort.Text;
            return result;
        }

        private string GetIISWebSitePath()
        {
            return string.Format(@"C:\Inetpub\wwwroot\wss\VirtualDirectories\{0}{1}", txbHostHeader.Text, txbPort.Text);
        }

        #region IInstallationControl Members

        private Installer _form;
        public Installer GetForm()
        {
            return _form;
        }

        public void SetForm(Installer installer)
        {
            _form = installer;
        }

        private string GetInternetWebApplicationURL()
        {
            if (RegistryAccess.PropertyExists(Registry.LocalMachine, Constants.CspRegistryKey, "CSPInternetWebApplication"))
                return RegistryAccess.GetStringProperty(Registry.LocalMachine, Constants.CspRegistryKey, "CSPInternetWebApplication");
            else
                return string.Empty;
        }

        private bool ValidateInputs()
        {
            if (txbPort.Text.Length > 0)
            {
                try
                {
                    int i = Convert.ToInt32(txbPort.Text);
                }
                catch
                {
                    MessageBox.Show(CSP.Package.labels.CspInstallError_PortInteger, CSP.Package.labels.CspInstallError_Title, MessageBoxButtons.OK, MessageBoxIcon.Error);
                    txbPort.Focus();
                    txbPort.Select();
                    return false;
                }
            }

            if (txbLogin.Text.Length == 0)
            {
                MessageBox.Show(CSP.Package.labels.CspInstallError_LoginNoEmpty, CSP.Package.labels.CspInstallError_Title, MessageBoxButtons.OK, MessageBoxIcon.Error);
                txbLogin.Focus();
                txbLogin.Select();
                return false;
            }

            if (txbEmail.Text.Length == 0)
            {
                MessageBox.Show(CSP.Package.labels.CspInstallError_EmailNoEmpty, CSP.Package.labels.CspInstallError_Title, MessageBoxButtons.OK, MessageBoxIcon.Error);
                txbEmail.Focus();
                txbEmail.Select();
                return false;
            }

            if (chkApid.Checked)
            {
                if (txbApiduser.Text.Length == 0)
                {
                    MessageBox.Show(CSP.Package.labels.CspInstallError_UsernameNoEmpty, CSP.Package.labels.CspInstallError_Title, MessageBoxButtons.OK, MessageBoxIcon.Error);
                    txbApiduser.Focus();
                    txbApiduser.Select();
                    return false;
                }

                if (txbApidpwd.Text.Length == 0)
                {
                    MessageBox.Show(CSP.Package.labels.CspInstallError_PasswordNoEmpty, CSP.Package.labels.CspInstallError_Title, MessageBoxButtons.OK, MessageBoxIcon.Error);
                    txbApidpwd.Focus();
                    txbApidpwd.Select();
                    return false;
                }

                if (!txbApidpwd.Text.Equals(txbApidpwd2.Text))
                {
                    MessageBox.Show(CSP.Package.labels.CspInstallError_PasswordNoMatch, CSP.Package.labels.CspInstallError_Title, MessageBoxButtons.OK, MessageBoxIcon.Error);
                    txbApidpwd.Focus();
                    txbApidpwd.Select();
                    return false;
                }

            }

            return true;
        }


        public bool Next()
        {
            try
            {
                if (ValidateInputs())
                {

                    GetForm().AddToLog("----------------------------------------------");
                    GetForm().AddToLog(CSP.Package.labels.CspInstallLog_InternetExtendedWebApplicationStart);

                    // First, we extend the internet web application to the new zone
                    SPWebApplication webApplication = SPWebApplication.Lookup(new Uri(GetInternetWebApplicationURL()));
                    ExtendWebApp(webApplication, txbDescription.Text, txbHostHeader.Text, txbPort.Text.Length == 0 ? 80 : Convert.ToInt32(txbPort.Text), GetWebApplicationUrl(), GetIISWebSitePath(), true, false, false, SPUrlZone.Custom);
                    
                    // Then, we set up anonymous access to the extended web application
                    SetAnonymousAccess();

                    // Finally, we set up the FBA information
                    Process proces = new Process();
                    proces.StartInfo.FileName = _executionPath;
                    string arguments = string.Format(@"{0}", new string[] { GetWebApplicationUrl() });

                    GetForm().AddToLog("   "+labels.CspInstallLog_Arguments+": " + arguments);

                    proces.StartInfo.Arguments = arguments;
                    proces.StartInfo.UseShellExecute = false;
                    proces.StartInfo.RedirectStandardOutput = true;
                    proces.StartInfo.RedirectStandardError = true;
                    proces.Start();
                    string error = proces.StandardError.ReadToEnd();
                    string output = proces.StandardOutput.ReadToEnd();
                    proces.WaitForExit();
                    if (error != string.Empty)
                    {
                        throw new ApplicationException(error);
                    }

                    GetForm().AddToLog(output);

                    return true;
                }
                else
                    return false;

            }
            catch (Exception ex)
            {
                GetForm().ShowException(ex);
                throw ex;
            }


        }

        public void Previous()
        {
        }

        public void Skip()
        {
        }

        #endregion


        public static void ExtendWebApp(SPWebApplication webApplication, string description, string hostHeader, int port, string loadBalancedUrl, string path, bool allowAnonymous, bool useNtlm, bool useSsl, SPUrlZone zone)  
        {  
            SPServerBinding serverBinding = null;   
            SPSecureBinding secureBinding = null;   
            if (!useSsl)   
            {   
                serverBinding = new SPServerBinding();   
                serverBinding.Port = port;   
                serverBinding.HostHeader = hostHeader;  
            }  
            else  
            {  
                secureBinding = new SPSecureBinding();  
                secureBinding.Port = port;  
            }  
            SPIisSettings settings = new SPIisSettings(description, allowAnonymous, useNtlm, serverBinding, secureBinding, new DirectoryInfo(path.Trim()));  
            
            webApplication.IisSettings.Add(zone, settings);  
            webApplication.AlternateUrls.SetResponseUrl(new SPAlternateUrl(new Uri(loadBalancedUrl), zone));  
            webApplication.AlternateUrls.Update();  
            webApplication.Update();  
            webApplication.Provision();  
            if (SPFarm.Local.TimerService.Instances.Count > 1)  
            {  
                Type webAppProvisionJobDefType = Type.GetType("Microsoft.SharePoint.Administration.SPWebApplicationProvisioningJobDefinition, Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c");
                ConstructorInfo webAppProvisionConstructor = webAppProvisionJobDefType.GetConstructor(Utilities.AllBindings, null, new Type[] { webApplication.GetType(), typeof(bool) }, null);  
                object definition = webAppProvisionConstructor.Invoke(new object[] { webApplication, false });  
                Utilities.SetPropertyValue(definition, "Schedule", new SPOneTimeSchedule(DateTime.Now));  
                Utilities.ExecuteMethod(definition, "Update", new Type[] {}, new object[] {});  
            }  
        }

        public int SetAnonymousAccess()
        {
            using (SPSite site = new SPSite(GetWebApplicationUrl()))
            {
                using (SPWeb web = site.OpenWeb())
                {
                    web.AnonymousState = SPWeb.WebAnonymousState.On;
                    web.Update();
                }
                return 1;
            }
        }

        private void ExtendInternetWebApplication_Load(object sender, EventArgs e)
        {
            TranslateLiterals();
            txbLogin.Text = Environment.UserDomainName + "\\" + Environment.UserName;
        }

        private void chkApid_CheckedChanged(object sender, EventArgs e)
        {
            txbApidpwd.ReadOnly = !chkApid.Checked;
            txbApidpwd2.ReadOnly = !chkApid.Checked;
            txbApiduser.ReadOnly = !chkApid.Checked;
        }

        private string GetWebApplicationDescription()
        {
            return string.Format("Sharepoint - {0}{1}", txbHostHeader.Text, txbPort.Text);
        }

        private void txbPort_TextChanged(object sender, EventArgs e)
        {
            txbDescription.Text = GetWebApplicationDescription();
        }

        private void txbHostHeader_TextChanged(object sender, EventArgs e)
        {
            txbDescription.Text = GetWebApplicationDescription();
        }

        private void TranslateLiterals()
        {
            richTextBox1.Text = CSP.Package.labels.ExtendInternetWebApplication_Intro;

            groupBox1.Text = CSP.Package.labels.IISWebSite_GroupBox;
            groupBox2.Text = CSP.Package.labels.ApplicationPoolCredentials_GroupBox;
            groupBox3.Text = CSP.Package.labels.OwnerInformation_GroupBox;
         
            label5.Text = CSP.Package.labels.Port_Label;
            label6.Text = CSP.Package.labels.HostHeader_Label;
            label2.Text = CSP.Package.labels.Description_Label;
            label9.Text = CSP.Package.labels.Email_Label;
            label10.Text = CSP.Package.labels.Login_Label;
            label7.Text = CSP.Package.labels.Username_Label;
            label4.Text = CSP.Package.labels.Password_Label;
            label3.Text = CSP.Package.labels.PasswordReType_Label;
         
            chkSSL.Text = CSP.Package.labels.UseSSL_Label;
            chkApid.Text = CSP.Package.labels.Configurable_Label;  
        }
  
    }
}
